﻿
using System.Runtime.CompilerServices;

namespace RainbowNavBar.View
{
    public partial class SettingView : Window
    {
        /// <summary>
        /// 文件密钥
        /// </summary>
        private readonly byte key = 0x5A;

        #region 窗体布局

        /// <summary>
        /// 窗体构造
        /// </summary>
        public SettingView()
        {
            InitializeComponent();
            this.Loaded += SettingView_Loaded;

            this.LocationChanged += SetEPopupBoxPint;

            // 窗口关闭：将ApplicationSettings设置为Null
            this.Closing += (s, e) => { ApplicationSettings = null; };
        }

        /// <summary>
        /// 窗体加载完成
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SettingView_Loaded(object sender, RoutedEventArgs e)
        {
            this.nav.SelectedIndex = 0;
            this.IsStartUp.IsChecked = AppConfig.StartUp;
            this.IsLocation.IsChecked = AppConfig.Location;
            this.IsOpenComputer.IsChecked = AppConfig.Computer;
        }

        /// <summary>
        /// 选项卡导航
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Nav_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            int _index = 0;
            switch (this.nav.SelectedIndex)
            {
                case 0: _index = 0; break;
                case 1: _index = 1; break;
                //case 2: _index = 2; break;
            };
            this.Tabs.SelectedIndex = _index;

        }

        #endregion

        #region 开机启动

        /// <summary>
        /// 关闭开机启动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void IsStartUp_Unchecked(object sender, RoutedEventArgs e)
        {
            SaveStartupSetting(false);
        }

        /// <summary>
        /// 开启开机启动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void IsStartUp_Checked(object sender, RoutedEventArgs e)
        {
            SaveStartupSetting(true);
        }

        /// <summary>
        /// 保存启动设置
        /// </summary>
        /// <param name="isChecked"></param>
        private void SaveStartupSetting(bool isChecked)
        {
            switch (isChecked)
            {
                case true:
                    this.StartUp();
                    break;
                case false:
                    this.RemoveFromStartup();
                    break;
                default:
            }
        }

        /// <summary>
        /// 开启自动启动
        /// </summary>
        private void StartUp()
        {
            try
            {
                using (RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true))
                {
                    if (key != null)
                    {
                        string appName = System.IO.Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location);
                        key.SetValue(appName, System.Reflection.Assembly.GetEntryAssembly().Location);
                    }
                }

                // 记忆状态
                AppConfig.StartUp = true;
                // 写入配置文件
                ApplicationConfig.configManager.SetAppConfigValue("StartUp", "True");

                Debug.WriteLine("Application added to startup.");
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"Failed to add application to startup: {ex.Message}");
            }
        }

        /// <summary>
        /// 关闭自动启动
        /// </summary>
        private void RemoveFromStartup()
        {
            try
            {
                using (RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true))
                {
                    if (key != null)
                    {
                        string appName = System.IO.Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location);
                        key.DeleteValue(appName, false);
                    }
                }


                // 记忆状态
                AppConfig.StartUp = false;
                // 写入配置文件
                ApplicationConfig.configManager.SetAppConfigValue("StartUp", "False");

                Debug.WriteLine("Application removed from startup.");
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"Failed to remove application from startup: {ex.Message}");
            }
        }

        #endregion

        #region 屏幕位置

        /// <summary>
        /// 导航在屏幕中的位置(开启)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void IsLocation_Checked(object sender, RoutedEventArgs e)
        {
            MainWindow.SetPointWLeft();

            foreach (TagData tagData in ApplicationConfig.TagListData)
            {
                tagData.TagLabel.HorizontalAlignment = HorizontalAlignment.Left;
                tagData.TagLabel.HorizontalContentAlignment = HorizontalAlignment.Right;
            }

            this.NavRight.Foreground = new SolidColorBrush((System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#808080"));
            this.NavLeft.Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#8bb0f2"));
        }

        /// <summary>
        /// 导航在屏幕中的位置(关闭)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void IsLocation_Unchecked(object sender, RoutedEventArgs e)
        {
            MainWindow.SetPointWRight();
            foreach (TagData tagData in ApplicationConfig.TagListData)
            {
                tagData.TagLabel.HorizontalAlignment = HorizontalAlignment.Right;
                tagData.TagLabel.HorizontalContentAlignment = HorizontalAlignment.Left;
            }
            this.NavRight.Foreground = new SolidColorBrush((System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#8bb0f2"));
            this.NavLeft.Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#808080"));
        }

        #endregion

        #region 我的电脑

        /// <summary>
        /// 开启我的电脑
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void IsOpenComputer_Checked(object sender, RoutedEventArgs e)
        {
            // 记忆状态
            AppConfig.Computer = true;
            // 写入配置文件
            ApplicationConfig.configManager.SetAppConfigValue("Computer", "True");
            // 设置标签状态
            IsOpenComputerTag(true);
        }

        /// <summary>
        /// 关闭我的电脑
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void IsOpenComputer_Unchecked(object sender, RoutedEventArgs e)
        {
            // 记忆状态
            AppConfig.Computer = false;
            // 写入配置文件
            ApplicationConfig.configManager.SetAppConfigValue("Computer", "False");
            // 设置标签状态
            IsOpenComputerTag(false);
        }

        /// <summary>
        /// 设置“我的电脑”是否显示，并写入到配置中
        /// </summary>
        /// <param name="sc">true:显示 false:不显示</param>
        private void IsOpenComputerTag(bool sc)
        {
            // 状态：我的电脑
            MainWindow.IsOpenComputer(sc);
        }

        #endregion

        #region 消息提示

        /// <summary>
        /// 消息框弹出位置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SetEPopupBoxPint(object sender, EventArgs e)
        {
            // 信息框弹出位置
            if (ApplicationTip != null && ApplicationTip.Owner == this)
            {
                ApplicationTip.Left = this.Left + ((this.Width / 2) - (ApplicationTip.Width / 2));
                ApplicationTip.Top = this.Top + 40;
            }
        }

        #endregion

        #region 按钮功能

        /// <summary>
        /// 打开微信支持
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void WeChat_Click(object sender, RoutedEventArgs e)
        {
            this.HintText.Text = "微信扫码赞助UP \\^o^/";
            this.HintImage.Source = new BitmapImage(new Uri("pack://application:,,,/image/support.jpg"));
            this.MaskLayer.Visibility = Visibility.Visible;
        }

        /// <summary>
        /// 打开支付宝支持
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Alipay_Click(object sender, RoutedEventArgs e)
        {

        }

        /// <summary>
        /// 跳转到主页
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
        {
            // 打开指定的 URL
            Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri) { UseShellExecute = true });
            e.Handled = true; // 阻止默认行为
        }

        /// <summary>
        /// 版本详情
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AppVersionDetail_Click(object sender, RoutedEventArgs e)
        {

        }

        /// <summary>
        /// 打开网站
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Image_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Process.Start(new ProcessStartInfo("http://mindev.cn") { UseShellExecute = true });
            e.Handled = true; // 阻止默认行为
        }

        private void MaskLayer_MouseDown(object sender, MouseButtonEventArgs e)
        {

            this.HintText.Text = string.Empty;
            this.HintImage.Source = null;
            this.MaskLayer.Visibility = Visibility.Collapsed;
        }

        /// <summary>
        /// 加入QQ群
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void QQ_Click(object sender, RoutedEventArgs e)
        {
            this.HintText.Text = "🐧 加入QQ群 \\^o^/";
            this.HintImage.Source = new BitmapImage(new Uri("pack://application:,,,/image/qq.jpg"));
            this.MaskLayer.Visibility = Visibility.Visible;
        }

        /// <summary>
        /// 点击应用图标调整到网站
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Image_MouseDown_Open(object sender, MouseButtonEventArgs e)
        {
            Process.Start(new ProcessStartInfo("http://mindev.cn") { UseShellExecute = true });
            e.Handled = true; // 阻止默认行为
        }

        /// <summary>
        /// 打开个人网站
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OpenUrl_Click(object sender, RoutedEventArgs e)
        {
            Process.Start(new ProcessStartInfo("http://mindev.cn") { UseShellExecute = true });
            e.Handled = true; // 阻止默认行为
        }

        /// <summary>
        /// 点击文本内容，加入QQ群
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Hyperlink_QQ(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
        {
            QQ_Click(null, null);
        }

        #endregion

        #region 备份数据

        /// <summary>
        /// 导出数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ExportData_Click(object sender, RoutedEventArgs e)
        {
            byte[] data = null, encryptedData = null;
            try
            {
                // 打开文件流
                using (FileStream fs = new(ApplicationConfig.ConfigPath, FileMode.Open, FileAccess.Read))
                using (BinaryReader reader = new(fs))
                {
                    // 读取二进制数据
                    data = reader.ReadBytes((int)fs.Length);
                }
                // 使用 XOR 密钥对数据进行加密
                encryptedData = ApplicationConfig.RemoveBomIfPresent(EncryptData(data, this.key));
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Error: " + ex.Message);
            }
            // 将数据保存为文件
            this.SaveToFile(encryptedData);
        }

        /// <summary>
        /// 导入数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ImportData_Click(object sender, RoutedEventArgs e)
        {
            this.OpenToFile();
        }

        /// <summary>
        /// 加密数据
        /// </summary>
        /// <param name="data">数据</param>
        /// <param name="key">加密密钥</param>
        /// <returns></returns>
        public static byte[] EncryptData(byte[] data, byte key)
        {
            byte[] encryptedData = new byte[data.Length];
            for (int i = 0; i < data.Length; i++)
            {
                encryptedData[i] = (byte)(data[i] ^ key); // XOR 加密
            }
            return encryptedData;
        }

        /// <summary>
        /// 解密数据（与加密相同，XOR 是对称的）
        /// </summary>
        /// <param name="data">数据</param>
        /// <param name="key">解密密钥</param>
        /// <returns></returns>
        public static byte[] DecryptData(byte[] data, byte key)
        {
            return EncryptData(data, key); // XOR 解密与加密相同
        }

        /// <summary>
        /// 将byte数组转换成字符串
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string ByteToString(byte[] data, bool UTF8 = false)
        {
            if (UTF8)
            {
                return Encoding.UTF8.GetString(data);
            }
            return BitConverter.ToString(data);
        }

        /// <summary>
        /// 打开保存文件对话框，让用户选择路径并保存内容到文件
        /// </summary>
        /// <param name="content">要保存的内容</param>
        /// <param name="filter">文件类型过滤器</param>
        public void SaveToFile(byte[] content, string filter = "彩虹导航备份文件 (*.mtd)|*.mtd")
        {
            // 创建 SaveFileDialog
            SaveFileDialog saveFileDialog = new()
            {
                Title = "选择保存路径",
                FileName = DateTime.Now.ToString("yyyy_MM_dd_HH_mm"),
                Filter = filter
            };

            // 显示对话框并获取结果
            if (saveFileDialog.ShowDialog() == true)
            {
                string filePath = saveFileDialog.FileName;

                try
                {
                    // 写入文件内容
                    using (FileStream fs = new(filePath, FileMode.Create, FileAccess.Write))
                    using (BinaryWriter writer = new(fs))
                    {
                        writer.Write(content);

                        //byte[] encodedContent = new UTF8Encoding(false).GetBytes(Encoding.UTF8.GetChars(content)); // 编码为 UTF-8 无 BOM
                        //writer.Write(encodedContent);
                    }
                    MessBox(this, "文件备份成功：" + System.IO.Path.GetFileName(saveFileDialog.FileName), EMColor.Success);
                    //Debug.WriteLine($"文件已成功保存到: {filePath}");
                }
                catch (Exception ex)
                {
                    MessBox(this, $"保存文件时发生错误：{ex.Message}", EMColor.Error);
                    //Debug.WriteLine($"保存文件时发生错误: {ex.Message}");
                }
            }
            else
            {
                MessBox(this, "您取消了备份操作。", EMColor.Info);
                //Debug.WriteLine("用户取消了保存操作。");
            }
        }

        /// <summary>
        /// 打开需要导入的文件
        /// </summary>
        public void OpenToFile()
        {
            OpenFileDialog openFileDialog = new()
            {
                Filter = "彩虹导航数据文件 (*.mtd)|*.mtd",  // 默认文件类型过滤器
                Title = "导入数据"  // 设置对话框的标题
            };

            if (openFileDialog.ShowDialog() == true)
            {
                byte[] data = null;
                // 打开文件流
                using (FileStream fs = new(openFileDialog.FileName, FileMode.Open, FileAccess.Read))
                using (BinaryReader reader = new(fs))
                {
                    // 读取二进制数据
                    data = reader.ReadBytes((int)fs.Length);
                    //Debug.WriteLine("直接读取 - [未解密]：" + BitConverter.ToString(data));
                }

                // 获取中文xml内容
                // string xmlContent = ByteToString(DecryptData(data, key), true).TrimStart();
                var RemoveBomData = ApplicationConfig.RemoveBomIfPresent(DecryptData(data, this.key));
                // Debug.WriteLine("[解密后]：" + BitConverter.ToString(RemoveBomData));

                string xmlContent = Encoding.UTF8.GetString(RemoveBomData).TrimStart();

                // 去除前部和尾部空格
                xmlContent = xmlContent.Trim();

                // 检查内容是否符合XML格式要求
                if (!ApplicationConfig.IsValidXml(xmlContent))
                {
                    MessBox(this, "文件格式错误！", EMColor.Error);
                    return;
                }

                // XmlDocument 对象 doc
                XmlDocument doc = new();
                doc.LoadXml(xmlContent);

                // 将 XmlDocument 转换为 XDocument
                XDocument xdoc = XDocument.Parse(doc.OuterXml);

                List<Dictionary<string, string>> dataRecords = XmlConfigManager.GetAllDataRecordsSync(xdoc);

                if (dataRecords != null)
                {
                    // 遍历 dataRecords 列表,将数据添加到ApplicationConfig列表中
                    foreach (var record in dataRecords)
                    {
                        // 设每个 Dictionary 中只有一个键值对，获取 TagData 对象
                        var tagData = new TagData
                        {
                            TagIndex = int.Parse(record["TagIndex"]),
                            TagLabel = new Label(),
                            TagType = (FunType)Convert.ToInt32(record["TagType"]),
                            TagEnable = Convert.ToBoolean(record["TagEnable"]),
                            TagName = record["TagName"],
                            TagDescription = record["TagDescription"],
                            TagAddress=record["TagAddress"],
                            TagColor=(System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString(record["TagColor"]),
                            TagColor_s=(Brush) new BrushConverter().ConvertFromString(record["TagColor"]),
                            TagIcon = ApplicationConfig.GetApplicationIconAsync(record["TagAddress"], (FunType)Convert.ToInt32(record["TagType"]))
                        };

                        // 判断 TagName 是否已存在于 TagListData 中
                        var existingTagData = ApplicationConfig.TagListData.FirstOrDefault(t => t.TagName == tagData.TagName);

                        if (existingTagData == null)
                        {
                            // 如果 TagName 不存在，检查 TagIndex 是否与已有元素重合
                            //int newTagIndex = tagData.TagIndex;
                            bool indexConflict;
                            do
                            {
                                // 如果 TagName 不存在，检查 TagIndex 是否与已有元素重合
                                indexConflict = ApplicationConfig.TagListData.Any(t => t.TagIndex == tagData.TagIndex);
                                if (indexConflict)
                                {
                                    // 如果 TagIndex 重合，则更新 TagIndex
                                    tagData.TagIndex = ApplicationConfig.TagListData.Count + 1; // 更新 TagIndex 为 TagListData 中元素的数量 + 1
                                }
                            }
                            while (indexConflict);

                            // 添加新的 TagData 到 TagListData
                            //ApplicationConfig.TagListData.Add(tagData);
                            SyncTag((int)tagData.TagType, tagData.TagName, tagData.TagEnable, tagData.TagDescription, tagData.TagAddress, tagData.TagColor.ToString(), tagData.TagIndex);
                        }
                    }
                    // 标签数据进行排序
                    ApplicationConfig.TagSorting();
                    // 对标签进行左右屏
                    if (this.IsLocation.IsChecked == true)
                    {
                        this.IsLocation_Checked(null, null);
                    }
                    else
                    {
                        this.IsLocation_Unchecked(null, null);
                    }
                    // 重新加载窗体标签
                    MainWindow.ReloadData();
                    // 弹出信息提示
                    MessBox(this, "文件导入成功！", EMColor.Success);
                }
            }
        }

        /// <summary>
        /// 导入数据同步到本地
        /// </summary>
        /// <param name="index"></param>
        /// <param name="tagName"></param>
        /// <param name="isEnable"></param>
        /// <param name="tagDescription"></param>
        /// <param name="tagAddress"></param>
        /// <param name="tagColor"></param>
        /// <param name="tagIndex"></param>
        private void SyncTag(int index, string tagName, bool isEnable, string tagDescription, string tagAddress, string tagColor, int tagIndex)
        {
            // 创建标签
            Label _label = new()
            {
                Width = 10,
                Height = 30,
                Content = tagName,
                Background = new SolidColorBrush((System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString(tagColor)),
            };

            // 创建对象
            TagData _td = new()
            {
                TagIndex = tagIndex,
                TagLabel = _label,
                TagType = (FunType)index,
                TagEnable = isEnable,
                TagName = tagName,
                TagDescription = tagDescription,
                TagAddress = tagAddress,
                TagColor = (System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString(tagColor),
                TagColor_s = (Brush)new BrushConverter().ConvertFromString(tagColor),
                //TagIcon = GetTypeIcon((FunType)Convert.ToInt32(record["TagType"])),                     
                TagIcon = ApplicationConfig.GetApplicationIconAsync(tagAddress, (FunType)index),
            };

            // 通知列表更新数据
            TagManagement.SyncDataLocal(_td);

            // 添加对象到全局列表中
            ApplicationConfig.TagAdd(_td,
            new Dictionary<string, string>
            {
                {"TagIndex",tagIndex.ToString() },
                {"TagType",index.ToString() },
                {"TagName",tagName },
                {"TagEnable",isEnable.ToString() },
                {"TagDescription",tagDescription },
                {"TagAddress",tagAddress },
                {"TagColor",tagColor },
            });
        }

        #endregion

    }
}
